﻿namespace UnityEditor
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Runtime.InteropServices;
    using UnityEditorInternal;
    using UnityEngine;

    internal class AssembleEditorSkin : EditorWindow
    {
        private float gamma = s_Gamma;
        private float inBlack = s_InBlack;
        private float inWhite = s_InWhite;
        private const string kDestDarkFile = "Editor Default Resources/Builtin Skins/Generated/DarkSkin";
        private const string kDestLightFile = "Editor Default Resources/Builtin Skins/Generated/LightSkin";
        private const string kGeneratedDirectory = "Editor Default Resources/Builtin Skins/Generated/";
        private const string kSrcDarkSkins = "Editor Default Resources/Builtin Skins/DarkSkin/Skins/";
        private static readonly string[] kSrcImageDirs = new string[] { "Editor Default Resources/Builtin Skins/LightSkin/Images/", "Editor Default Resources/Builtin Skins/LightSkin/FlowImages/" };
        private const string kSrcLightSkins = "Editor Default Resources/Builtin Skins/LightSkin/Skins/";
        private static readonly string[] kSrcOverrideImageDirs = new string[] { "Editor Default Resources/Builtin Skins/DarkSkin/Images/", "Editor Default Resources/Builtin Skins/DarkSkin/FlowImages/" };
        private const string kSrcSharedSkins = "Editor Default Resources/Builtin Skins/Shared/Skins/";
        private float outBlack = s_OutBlack;
        private float outWhite = s_OutWhite;
        private static float s_Gamma = 1.328f;
        private static float s_InBlack = 0f;
        private static float s_InWhite = 1f;
        private static float s_OutBlack = 0f;
        private static float s_OutWhite = 0.297f;
        private static float s_TextBrightness = 0.705f;
        private bool test;
        private float textBrightness = s_TextBrightness;

        private static void AddSkin(GUISkin source, SortedDictionary<string, GUIStyle> styles, GUISkin dest, bool includeBuiltins)
        {
            if (includeBuiltins)
            {
                dest.font = source.font;
                dest.settings.doubleClickSelectsWord = source.settings.doubleClickSelectsWord;
                dest.settings.tripleClickSelectsLine = source.settings.tripleClickSelectsLine;
                dest.settings.cursorColor = source.settings.cursorColor;
                dest.settings.cursorFlashSpeed = source.settings.cursorFlashSpeed;
                dest.settings.selectionColor = source.settings.selectionColor;
                dest.box = new GUIStyle(source.box);
                dest.button = new GUIStyle(source.button);
                dest.toggle = new GUIStyle(source.toggle);
                dest.label = new GUIStyle(source.label);
                dest.textField = new GUIStyle(source.textField);
                dest.textArea = new GUIStyle(source.textArea);
                dest.window = new GUIStyle(source.window);
                dest.horizontalSlider = new GUIStyle(source.horizontalSlider);
                dest.horizontalSliderThumb = new GUIStyle(source.horizontalSliderThumb);
                dest.verticalSlider = new GUIStyle(source.verticalSlider);
                dest.verticalSliderThumb = new GUIStyle(source.verticalSliderThumb);
                dest.horizontalScrollbar = new GUIStyle(source.horizontalScrollbar);
                dest.horizontalScrollbarThumb = new GUIStyle(source.horizontalScrollbarThumb);
                dest.horizontalScrollbarLeftButton = new GUIStyle(source.horizontalScrollbarLeftButton);
                dest.horizontalScrollbarRightButton = new GUIStyle(source.horizontalScrollbarRightButton);
                dest.verticalScrollbar = new GUIStyle(source.verticalScrollbar);
                dest.verticalScrollbarThumb = new GUIStyle(source.verticalScrollbarThumb);
                dest.verticalScrollbarUpButton = new GUIStyle(source.verticalScrollbarUpButton);
                dest.verticalScrollbarDownButton = new GUIStyle(source.verticalScrollbarDownButton);
                dest.scrollView = new GUIStyle(source.scrollView);
            }
            foreach (GUIStyle style in source.customStyles)
            {
                styles[style.name] = new GUIStyle(style);
            }
        }

        private static void AddSkinsFromDir(GUISkin dest, string dir)
        {
            SortedDictionary<string, GUIStyle> styles = new SortedDictionary<string, GUIStyle>();
            foreach (GUIStyle style in dest.customStyles)
            {
                styles[style.name] = style;
            }
            foreach (FileInfo info in new DirectoryInfo(Application.dataPath + "/" + dir).GetFiles("*.guiskin"))
            {
                GUISkin source = (GUISkin) AssetDatabase.LoadAssetAtPath("Assets/" + dir + info.Name, typeof(GUISkin));
                AddSkin(source, styles, dest, info.Name == "base.guiskin");
            }
            foreach (FileInfo info2 in new DirectoryInfo(Application.dataPath + "/" + dir).GetFiles("*.GUISkin"))
            {
                GUISkin skin2 = (GUISkin) AssetDatabase.LoadAssetAtPath("Assets/" + dir + info2.Name, typeof(GUISkin));
                AddSkin(skin2, styles, dest, info2.Name == "base.GUISkin");
            }
            GUIStyle[] array = new GUIStyle[styles.Count];
            styles.Values.CopyTo(array, 0);
            dest.customStyles = array;
            EditorUtility.SetDirty(dest);
        }

        private static void AdjustTextures(IEnumerable<Texture2D> incoming)
        {
            IEnumerator<Texture2D> enumerator = incoming.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    Texture2D current = enumerator.Current;
                    DarkenTexture(current, current);
                }
            }
            finally
            {
                if (enumerator == null)
                {
                }
                enumerator.Dispose();
            }
        }

        private static float ApplyLevels(float color, float inBlack, float inWhite, float gamma, float outBlack, float outWhite)
        {
            color = Mathf.Clamp01((color - inBlack) / (inWhite - inBlack));
            color = Mathf.Pow(color, gamma);
            return (outBlack + (color * (outWhite - outBlack)));
        }

        private static GUISkin BuildSkin(string destFilePath, params string[] sourceDirPaths)
        {
            GUISkin asset = AssetDatabase.LoadAssetAtPath("Assets/" + destFilePath + ".guiskin", typeof(GUISkin)) as GUISkin;
            if (asset == null)
            {
                string path = "Assets/" + destFilePath + ".guiskin";
                AssetDatabase.DeleteAsset(path);
                asset = ScriptableObject.CreateInstance<GUISkin>();
                AssetDatabase.CreateAsset(asset, path);
            }
            asset.customStyles = new GUIStyle[0];
            foreach (string str2 in sourceDirPaths)
            {
                AddSkinsFromDir(asset, str2);
            }
            return asset;
        }

        public static GUISkin CopyLightToDark(GUISkin srcSkin, string[] sourceTexturePaths, string[] overrideTexturePaths, string dest)
        {
            Dictionary<Texture2D, Texture2D> remap = new Dictionary<Texture2D, Texture2D>();
            foreach (string str in sourceTexturePaths)
            {
                foreach (KeyValuePair<Texture2D, Texture2D> pair in LoadAllTexturesAtPath(str))
                {
                    remap[pair.Key] = pair.Value;
                }
            }
            AdjustTextures(remap.Values);
            List<Texture2D> list = new List<Texture2D>();
            foreach (string str2 in overrideTexturePaths)
            {
                list.AddRange(LoadAllTexturesAtPath(str2).Values);
            }
            foreach (Texture2D textured in list)
            {
                foreach (KeyValuePair<Texture2D, Texture2D> pair2 in remap)
                {
                    if (pair2.Value.name == textured.name)
                    {
                        UnityEngine.Object.DestroyImmediate(remap[pair2.Key]);
                        remap[pair2.Key] = textured;
                        break;
                    }
                }
            }
            GUISkin asset = null;
            if (srcSkin != null)
            {
                asset = AssetDatabase.LoadAssetAtPath("Assets/" + dest + ".guiskin", typeof(GUISkin)) as GUISkin;
                if (asset == null)
                {
                    string path = "Assets/" + dest + ".GUISkin";
                    AssetDatabase.DeleteAsset(path);
                    asset = ScriptableObject.CreateInstance<GUISkin>();
                    AssetDatabase.CreateAsset(asset, path);
                }
                RemapSkin(srcSkin, asset, remap);
                RecolorSkin(asset);
            }
            List<UnityEngine.Object> objs = new List<UnityEngine.Object>();
            foreach (Texture2D textured2 in remap.Values)
            {
                if (!EditorUtility.IsPersistent(textured2))
                {
                    objs.Add(textured2);
                }
                else
                {
                    Debug.Log("skipping tex " + textured2.name);
                }
            }
            SaveAllFilesToAsset(objs, dest + "_Textures");
            return asset;
        }

        private static void DarkenTexture(Texture2D tex, Texture2D dest)
        {
            Color[] pixels = tex.GetPixels(0);
            for (int i = 0; i < pixels.Length; i++)
            {
                Color color = pixels[i];
                color.r = ApplyLevels(color.r, s_InBlack, s_InWhite, s_Gamma, s_OutBlack, s_OutWhite);
                color.g = ApplyLevels(color.g, s_InBlack, s_InWhite, s_Gamma, s_OutBlack, s_OutWhite);
                color.b = ApplyLevels(color.b, s_InBlack, s_InWhite, s_Gamma, s_OutBlack, s_OutWhite);
                pixels[i] = color;
            }
            dest.SetPixels(pixels, 0);
            dest.Apply();
        }

        public static void DoIt()
        {
            Directory.CreateDirectory("Assets/Editor Default Resources/Builtin Skins/Generated/");
            string[] sourceDirPaths = new string[] { "Editor Default Resources/Builtin Skins/LightSkin/Skins/", "Editor Default Resources/Builtin Skins/Shared/Skins/" };
            GUISkin dest = CopyLightToDark(BuildSkin("Editor Default Resources/Builtin Skins/Generated/LightSkin", sourceDirPaths), kSrcImageDirs, kSrcOverrideImageDirs, "Editor Default Resources/Builtin Skins/Generated/DarkSkin");
            AddSkinsFromDir(dest, "Editor Default Resources/Builtin Skins/DarkSkin/Skins/");
            AddSkinsFromDir(dest, "Editor Default Resources/Builtin Skins/Shared/Skins/");
            AssetDatabase.SaveAssets();
            InternalEditorUtility.RepaintAllViews();
            InternalEditorUtility.RequestScriptReload();
        }

        private static void HLS2RGB(float h, float l, float s, out float r, out float g, out float b)
        {
            r = l;
            g = l;
            b = l;
            float num = (l > 0.5f) ? ((l + s) - (l * s)) : (l * (1f + s));
            if (num > 0f)
            {
                float num2 = (l + l) - num;
                float num3 = (num - num2) / num;
                h *= 6f;
                int num4 = (int) h;
                float num5 = h - num4;
                float num6 = (num * num3) * num5;
                float num7 = num2 + num6;
                float num8 = num - num6;
                switch (num4)
                {
                    case 0:
                        r = num;
                        g = num7;
                        b = num2;
                        break;

                    case 1:
                        r = num8;
                        g = num;
                        b = num2;
                        break;

                    case 2:
                        r = num2;
                        g = num;
                        b = num7;
                        break;

                    case 3:
                        r = num2;
                        g = num8;
                        b = num;
                        break;

                    case 4:
                        r = num7;
                        g = num2;
                        b = num;
                        break;

                    case 5:
                        r = num;
                        g = num2;
                        b = num8;
                        break;
                }
            }
        }

        private static void Init()
        {
            AssembleEditorSkin window = (AssembleEditorSkin) EditorWindow.GetWindow(typeof(AssembleEditorSkin));
            window.inBlack = s_InBlack;
            window.inWhite = s_InWhite;
            window.gamma = s_Gamma;
            window.outBlack = s_OutBlack;
            window.outWhite = s_OutWhite;
            window.textBrightness = s_TextBrightness;
        }

        private static Dictionary<Texture2D, Texture2D> LoadAllTexturesAtPath(string path)
        {
            Dictionary<Texture2D, Texture2D> dictionary = new Dictionary<Texture2D, Texture2D>();
            foreach (FileInfo info in new DirectoryInfo(Application.dataPath + "/" + path).GetFiles("*.png"))
            {
                Texture2D textured = (Texture2D) AssetDatabase.LoadAssetAtPath("Assets/" + path + info.Name, typeof(Texture2D));
                if (textured != null)
                {
                    WWW www = new WWW("file://" + info.FullName);
                    Texture2D texture = www.texture;
                    if (texture != null)
                    {
                        texture.name = info.Name;
                        texture.wrapMode = TextureWrapMode.Clamp;
                        dictionary[textured] = texture;
                    }
                }
            }
            return dictionary;
        }

        private void MakeButtonRow(params string[] styles)
        {
            GUILayout.BeginHorizontal(new GUILayoutOption[0]);
            foreach (string str in styles)
            {
                this.test = GUILayout.Toggle(this.test, str, str, new GUILayoutOption[0]);
            }
            GUILayout.EndHorizontal();
        }

        public void OnGUI()
        {
            GUILayout.Label("Image Remapping", EditorStyles.boldLabel, new GUILayoutOption[0]);
            GUI.changed = false;
            s_InBlack = this.inBlack = EditorGUILayout.Slider(new GUIContent("In Black"), this.inBlack, 0f, 1f, new GUILayoutOption[0]);
            s_Gamma = this.gamma = EditorGUILayout.Slider(new GUIContent("Gamma"), this.gamma, 0f, 2f, new GUILayoutOption[0]);
            s_InWhite = this.inWhite = EditorGUILayout.Slider(new GUIContent("In White"), this.inWhite, 0f, 1f, new GUILayoutOption[0]);
            s_OutBlack = this.outBlack = EditorGUILayout.Slider(new GUIContent("Out Black"), this.outBlack, 0f, 1f, new GUILayoutOption[0]);
            s_OutWhite = this.outWhite = EditorGUILayout.Slider(new GUIContent("Out White"), this.outWhite, 0f, 1f, new GUILayoutOption[0]);
            s_TextBrightness = this.textBrightness = EditorGUILayout.Slider(new GUIContent("Text Brightness "), this.textBrightness, 0f, 1f, new GUILayoutOption[0]);
            GUILayout.Label("Background: " + ApplyLevels(0.76f, s_InBlack, s_InWhite, s_Gamma, s_OutBlack, s_OutWhite), new GUILayoutOption[0]);
            if (GUILayout.Button("DO IT - update all controls", "button", new GUILayoutOption[0]))
            {
                DoIt();
            }
            bool flag = EditorGUIUtility.skinIndex != 0;
            if (EditorGUILayout.Toggle("Use Dark Skin", flag, new GUILayoutOption[0]) != flag)
            {
                InternalEditorUtility.SwitchSkinAndRepaintAllViews();
            }
            string[] styles = new string[] { "button", "toggle", "label", "radio" };
            this.MakeButtonRow(styles);
            string[] textArray2 = new string[] { "button", "buttonleft", "buttonmid", "buttonright", "popup", "DropDown" };
            this.MakeButtonRow(textArray2);
            string[] textArray3 = new string[] { "largebutton", "largebuttonleft", "largebuttonmid", "largebuttonright", "largepopup", "largeDropDown" };
            this.MakeButtonRow(textArray3);
            string[] textArray4 = new string[] { "button", "boldLabel", "label" };
            this.MakeButtonRow(textArray4);
            string[] textArray5 = new string[] { "button", "ControlLabel", "minibutton", "minipopup", "minipulldown" };
            this.MakeButtonRow(textArray5);
            string[] textArray6 = new string[] { "button", "ControlLabel", "minibuttonleft", "minibuttonmid", "minibuttonright", "miniBoldLabel" };
            this.MakeButtonRow(textArray6);
            string[] textArray7 = new string[] { "button", "label", "IN Label", "TextField", "TextArea" };
            this.MakeButtonRow(textArray7);
        }

        private static Color RecalcColor(Color c)
        {
            float num;
            float num2;
            float num3;
            RGB2HLS(c.r, c.g, c.b, out num, out num2, out num3);
            num2 = s_TextBrightness - (s_TextBrightness * num2);
            Color color = new Color(0f, 0f, 0f, c.a);
            HLS2RGB(num, num2, num3, out color.r, out color.g, out color.b);
            return color;
        }

        private static void RecolorSkin(GUISkin skin)
        {
            RecolorStyle(skin.box);
            RecolorStyle(skin.button);
            RecolorStyle(skin.toggle);
            RecolorStyle(skin.label);
            RecolorStyle(skin.textField);
            RecolorStyle(skin.textArea);
            RecolorStyle(skin.window);
            RecolorStyle(skin.horizontalSlider);
            RecolorStyle(skin.horizontalSliderThumb);
            RecolorStyle(skin.verticalSlider);
            RecolorStyle(skin.verticalSliderThumb);
            RecolorStyle(skin.horizontalScrollbar);
            RecolorStyle(skin.horizontalScrollbarThumb);
            RecolorStyle(skin.horizontalScrollbarLeftButton);
            RecolorStyle(skin.horizontalScrollbarRightButton);
            RecolorStyle(skin.verticalScrollbar);
            RecolorStyle(skin.verticalScrollbarThumb);
            RecolorStyle(skin.verticalScrollbarUpButton);
            RecolorStyle(skin.verticalScrollbarDownButton);
            RecolorStyle(skin.scrollView);
            foreach (GUIStyle style in skin.customStyles)
            {
                RecolorStyle(style);
            }
        }

        private static void RecolorStyle(GUIStyle s)
        {
            s.normal.textColor = RecalcColor(s.normal.textColor);
            s.active.textColor = RecalcColor(s.active.textColor);
            s.hover.textColor = RecalcColor(s.hover.textColor);
            s.focused.textColor = RecalcColor(s.focused.textColor);
            s.onNormal.textColor = RecalcColor(s.onNormal.textColor);
            s.onActive.textColor = RecalcColor(s.onActive.textColor);
            s.onHover.textColor = RecalcColor(s.onHover.textColor);
            s.onFocused.textColor = RecalcColor(s.onFocused.textColor);
        }

        private static void RegenerateAllIconsWithMipLevels()
        {
            GenerateIconsWithMipLevels.GenerateAllIconsWithMipLevels();
        }

        private static void RegenerateSelectedIconsWithMipLevels()
        {
            GenerateIconsWithMipLevels.GenerateSelectedIconsWithMips();
        }

        private static void RemapSkin(GUISkin source, GUISkin dest, Dictionary<Texture2D, Texture2D> remap)
        {
            dest.font = source.font;
            dest.settings.doubleClickSelectsWord = source.settings.doubleClickSelectsWord;
            dest.settings.tripleClickSelectsLine = source.settings.tripleClickSelectsLine;
            dest.settings.cursorColor = RecalcColor(source.settings.cursorColor);
            dest.settings.cursorFlashSpeed = source.settings.cursorFlashSpeed;
            dest.settings.selectionColor = source.settings.selectionColor;
            dest.box = RemapStyle(source.box, remap);
            dest.button = RemapStyle(source.button, remap);
            dest.toggle = RemapStyle(source.toggle, remap);
            dest.label = RemapStyle(source.label, remap);
            dest.textField = RemapStyle(source.textField, remap);
            dest.textArea = RemapStyle(source.textArea, remap);
            dest.window = RemapStyle(source.window, remap);
            dest.horizontalSlider = RemapStyle(source.horizontalSlider, remap);
            dest.horizontalSliderThumb = RemapStyle(source.horizontalSliderThumb, remap);
            dest.verticalSlider = RemapStyle(source.verticalSlider, remap);
            dest.verticalSliderThumb = RemapStyle(source.verticalSliderThumb, remap);
            dest.horizontalScrollbar = RemapStyle(source.horizontalScrollbar, remap);
            dest.horizontalScrollbarThumb = RemapStyle(source.horizontalScrollbarThumb, remap);
            dest.horizontalScrollbarLeftButton = RemapStyle(source.horizontalScrollbarLeftButton, remap);
            dest.horizontalScrollbarRightButton = RemapStyle(source.horizontalScrollbarRightButton, remap);
            dest.verticalScrollbar = RemapStyle(source.verticalScrollbar, remap);
            dest.verticalScrollbarThumb = RemapStyle(source.verticalScrollbarThumb, remap);
            dest.verticalScrollbarUpButton = RemapStyle(source.verticalScrollbarUpButton, remap);
            dest.verticalScrollbarDownButton = RemapStyle(source.verticalScrollbarDownButton, remap);
            dest.scrollView = RemapStyle(source.scrollView, remap);
            List<GUIStyle> list = new List<GUIStyle>();
            foreach (GUIStyle style in source.customStyles)
            {
                list.Add(RemapStyle(style, remap));
            }
            dest.customStyles = list.ToArray();
        }

        private static GUIStyle RemapStyle(GUIStyle src, Dictionary<Texture2D, Texture2D> remaps)
        {
            GUIStyle style;
            return new GUIStyle(src) { normal = { background = RemapTex(style.normal.background, remaps) }, active = { background = RemapTex(style.active.background, remaps) }, hover = { background = RemapTex(style.hover.background, remaps) }, focused = { background = RemapTex(style.focused.background, remaps) }, onNormal = { background = RemapTex(style.onNormal.background, remaps) }, onActive = { background = RemapTex(style.onActive.background, remaps) }, onHover = { background = RemapTex(style.onHover.background, remaps) }, onFocused = { background = RemapTex(style.onFocused.background, remaps) } };
        }

        private static Texture2D RemapTex(Texture2D src, Dictionary<Texture2D, Texture2D> remaps)
        {
            if (src == null)
            {
                return null;
            }
            return (!remaps.ContainsKey(src) ? src : remaps[src]);
        }

        private static void RGB2HLS(float r, float g, float b, out float h, out float l, out float s)
        {
            h = 0f;
            s = 0f;
            l = 0f;
            float num = Mathf.Max(Mathf.Max(r, g), b);
            float num2 = Mathf.Min(Mathf.Min(r, g), b);
            l = (num2 + num) / 2f;
            if (((double) l) > 0.0)
            {
                float num3 = num - num2;
                s = num3;
                if (((double) s) > 0.0)
                {
                    s /= (l > 0.5f) ? ((2f - num) - num2) : (num + num2);
                    float num4 = (num - r) / num3;
                    float num5 = (num - g) / num3;
                    float num6 = (num - b) / num3;
                    if (r == num)
                    {
                        h = (g != num2) ? (1f - num5) : (5f + num6);
                    }
                    else if (g == num)
                    {
                        h = (b != num2) ? (3f - num6) : (1f + num4);
                    }
                    else
                    {
                        h = (r != num2) ? (5f - num4) : (3f + num5);
                    }
                    h /= 6f;
                    if (h == 1f)
                    {
                        h = 0f;
                    }
                }
            }
        }

        private static void SaveAllFilesToAsset(List<UnityEngine.Object> objs, string fName)
        {
            string path = "Assets/" + fName + ".asset";
            AssetDatabase.CreateAsset(objs[0], path);
            for (int i = 1; i < objs.Count; i++)
            {
                AssetDatabase.AddObjectToAsset(objs[i], path);
            }
        }
    }
}

